Описание выбранных данных: Представлен набор экспериментальных исследований эффекта антидепрессантов влиять на память человека в зависимости от состояния человека. В качестве испутыемых выступали жители Исландии.
Link: https://www.kaggle.com/steveahn/memory-test-on-drugged-islanders-data
Особенности:
*Дозировки следовали в соотношении 1:1. Воспоминания записывались за 10 минут до начала тестирования Участники тестировались каждый день на протяжении 1 недели
Поставлены утверждения:
Препараты долгосрочного применения влияют на работу мозга, возможности памяти человека.
Позитивные воспоминания являются более глубокими и объемными для представления.
Участники: 25+, хорошие образование и умственные способности
Контент: Файл с предоставленной информацией содержит информацию об участниках, информацию по лечению на протяжении экспериментов. Контроль проводился по проверке способности человека вспоминать замеренного во времени.
Источник: Данные предосталвены университетом UCLA, Калифорния. Автор утверждает о репрезентативности и действительности полученных данных.
Поставлены задачи:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.graph_objects as go
import plotly.express as px
import plotly.io as pio
pio.templates.default = "plotly_dark"
from plotly.subplots import make_subplots
from sklearn.utils import shuffle
from scipy import stats
Блок импорта библиотек.
В первой части импорт частоиспользуемых библиотек для работы с числами и таблицами. Специально для манипуляции с информацией и формирования ее в необходимые нам сущности.
Во второй части импорт библиотек реализующих визуальную поддержку в python.
В третей части ипорт привычных библиотек для работы с машинным обучением и статистикой. В дальнейшем будет использоваться импорт метода stats.linregress, который позволяет провести линейный регрессионный анализ и получить коэффициенты описывающей формулы. Способ получения значений реализован при помощи МНК.
При импорте данных получаем следующую таблицу
df = pd.read_csv('Islander_data.csv')
df.head(8)
Демонстрация типов данных представленных в таблице
df.info()
Краткая сводка по предоставленным данным.
data = df.copy()
df.describe()
По полученной сводке можно сделать следующие замечания.
Дозировка: мало информации что бы о чем то рассуждать.
Оценка памяти до тестирования: Среднее ~58с, СКО = 15.8, мода = 54с.
Сравнивая, можно предположить что применение антидипрессанта в виде преппаратов и плацебо, визуально, может влиять на работу памяти человека
plt.figure(figsize=(6,4))
sns.barplot(x='Drug',
y='Mem_Score_Before',
data=data,
order=data.Drug.unique().tolist())
plt.title('Distribution of Drugs')
Препараты испытывались в равных колличествах, следовательно, наша выборка может считаться сбалансированной.
fig = px.bar(data,
x="age",
y="Mem_Score_Before",
title="Память - возраст (ДО)",
color_discrete_sequence=['#F42272'])
fig.show()
fig = px.bar(data,
x="age",
y="Mem_Score_After",
title="Память - возраст (ПОСЛЕ)",
color_discrete_sequence=['#F42272'])
fig.show()
На графике представлены гистограммы отображающие состав испытуемых расположенном в зависимости оценки памяти от возраста до тестирования. Величина ячейки составляющей столбец прямопропрорциональная относительной величине оценки. По графику можно заметить что большая часть испытуемых принадлежит возрасту 25-55 лет. Явно выраженного показателя зависимости оценки памяти от возраста не очевидна.
plt.figure(figsize=(12,10))
x1, y1 = data['age'], data['Mem_Score_Before']
slope1, intercept1, r_value, p_value, std_err = stats.linregress(x1, y1)
plt.plot(x1, y1, 'o', label='BEFORE', )
plt.plot(x1, intercept1+slope1*x1, 'r', label='reg_before')
plt.xlabel('age')
plt.ylabel('Mem_Score_Before')
x2, y2 = data['age'], data['Mem_Score_After']
slope2, intercept2, r_value, p_value, std_err = stats.linregress(x2, y2)
plt.plot(x2, y2, 'v', label='AFTER')
plt.plot(x2, intercept2+slope2*x2, 'b', label='reg_after')
plt.xlabel('age')
plt.ylabel('Mem_Score_After')
plt.legend()
slope1, slope2 = round(slope1, 3), round(slope2, 3)
intercept1, intercept2 = round(intercept1, 3), round(intercept2, 3)
print(f'Regression before: {slope1}*x + {intercept1}')
print(f'Regression after: {slope2}*x + {intercept2}')
Анализируя полученный график точечной диаграммы и нанесенной на нее прямых линейной регрессии можно сделать следующие предположения:
С ростом возраста испытуемого, в среднем, показатели времени при тестировании памяти растут. Растут, стоит заметить, медленно, но тенденция наблюдается и визуально.
При визуальном анализе полученных прямых линейной регрессии, можно предположить что прямые почти параллельные, тогда в целом можно сделать предположение что показатель пересечения (intercept), который разнится ДО и ПОСЛЕ примерно на ~3.3с может быть приблизительной оценкой того на сколько замедлилась скорость работы памяти испытуемых
fig = px.scatter(data,
x="age",
y="Mem_Score_Before", title='Распределение оценки от возраста в виде облака точек (ДО)',
color_discrete_sequence=['orange'])
fig.show()
fig = px.scatter(data,
x="age",
y="Mem_Score_After", title='Распределение оценки от возраста в виде облака точек (ПОСЛЕ)',
color_discrete_sequence=['orange'])
fig.show()
На данной точечной диаграмме уже более заметна возможная тенденция к среднему увеличению способности памяти в зависимости от уменьшения возраста. Зависимость отрицательная. На диаграмме рассеивания для случая замеров после употребления препаратов заметна тенденция повсеместного среднего увеличения времения воспоминаний -> ухуджение показателей памяти, но можно заметить что показатели более молодой части выборки ухудшаются сильнее чем у взрослых
Данные тенденции можно проверить проведя простой анализ "топов" в выборке. Анализ "топов" представлен ниже.
fig1 = px.bar(data.sort_values('age', ascending=False)[:15][::-1],
x='Mem_Score_Before', y='first_name',
title='Обследуемые ТОП 15 по рейтингу памяти (ДО)',
text='Mem_Score_Before',
orientation='h')
fig1.show()
fig2 = px.bar(data.sort_values('age', ascending=False)[:15][::-1],
x='Mem_Score_After', y='first_name',
title='Обследуемые ТОП 15 по рейтингу памяти (ПОСЛЕ)',
text='Mem_Score_After',
orientation='h')
fig2.show()
По данному графику можно взглянуть на тенденцию изменения показателей для "топов"
sns.pairplot(data)
Данные графики представлены в виде ознакомительной информации которая лучше помогает понять распределение данных Гистограммы описывают распределение данных, даиграммы рассеяния показывают общее распредление признаком в зависимости с другими
Так же интересно взглянуть на самый левый нижний график, т.к анализ такой зависимости ранее не проводился. Он отображает зависимость изменения показателя отметки за тестирование памяти от возраста испытумых. Взглянем на график подробней
fig = px.scatter(data,
x="age",
y="Diff", title='Распределение оценки от возраста в виде облака точек (ПОСЛЕ)',
color_discrete_sequence=['orange'])
fig.show()
fig = px.bar(data,
x='age', y='Diff',
title='Обследуемые ТОП 15 по рейтингу памяти (ПОСЛЕ)',
text='age',
orientation='v')
fig.show()
При визуальном анализе можно сделать выводы:
grgs = data.groupby(["Drug","Happy_Sad_group"])[["Mem_Score_After"]].mean().reset_index()
fig = px.bar(grgs[['Drug', 'Mem_Score_After','Happy_Sad_group']].sort_values(
'Mem_Score_After', ascending=False),
y="Mem_Score_After",
x="Drug",
color='Happy_Sad_group',
template='plotly_dark')
fig.show()
Группы по признакам воспоминаний также сбалансированы. Средние показатели для каждой группы и подгруппы:
fig = px.scatter(data,
x="Mem_Score_Before",
y="Mem_Score_After",
color="Drug",
facet_col="Drug",
color_continuous_scale=px.colors.sequential.Viridis, render_mode="webgl")
fig.show()
fig = px.scatter(data,
x="Mem_Score_Before",
y="Mem_Score_After",
color="Happy_Sad_group",
facet_col="Happy_Sad_group",
color_continuous_scale=px.colors.sequential.Viridis, render_mode="webgl")
fig.show()
На данных диаграммах рассеивания видна тенденция изменения оценок до и после тестирования. Чем сильнее направление большего измененеия облака изменяется от линейной зависимости оценок тем сильнее влияние препаратов. Если это отклонение относительно прямой направлено против часовой стрелки, тобишь к большим значениям коэффициента, то воздействие препаратов сказывается сильнее и ухудшает результаты оценки памяти, в ином случае, полностью зеркально обратная ситуация.
Первый график составлен из трех групп по препаратам.
Второй график составлен из двух групп по типу воспоминаний
Очень часто в экспериментах и исследованиях возникает необходимость сравнить несколько групп между собой. В таком случае мы можем применять однофакторный дисперсионный анализ. Та переменная, которая будет разделять наших испытуемых или наблюдения на группы (номинативная переменная с нескольким градациями, в случае данной задачи это название наркотика) называется независимой переменной. А та количественная переменная, по степени выраженности которой мы сравниваем группы, называется зависимая переменная (в случае данной задачи переменная diff отражающая изменение оценки памяти и представляющая из себя время изменения).
Поставлена задача выяснить, отличаются ли средние изменений оценок памяти при применении препаратов и плацебо. Для возможности применений необходимо удовлетворение следующих условий:
Поставлена следующая гипотеза
Прежде чем приступить к проверке гипотезы, необходимо провести проверку ограничений на применение диспресионного анализа
data_for_anova = pd.DataFrame()
data = shuffle(data)
data_for_anova['A'] = data[data['Drug'] == 'A']['Diff'][:50].to_list()
data_for_anova['T'] = data[data['Drug'] == 'T']['Diff'][:50].to_list()
data_for_anova['S'] = data[data['Drug'] == 'S']['Diff'][:50].to_list()
data_for_anova.plot(figsize=(15,5), grid=True)
plt.ylabel('Diff')
data_for_anova.hist(figsize=(15,10))
По полученным графикам можно утверждать что распределения подчиняются нормальному закону распределения (данное предположение высказано на основе представленного выше графического способа) - следовательно можно воспользоваться диспресионным анализом для проверки поставленных гипотез о среднем
A = data_for_anova['A']
T = data_for_anova['T']
S = data_for_anova['S']
print( 'mean value for drug "A" = ', round(A.mean(), 5))
print( 'mean value for drug "T" = ', round(T.mean(), 5))
print( 'mean value for drug "S" = ', round(S.mean(), 5))
print( 'std for drug "A" = ', round(A.std(), 5))
print( 'std for drug "T" = ', round(T.std(), 5))
print( 'std for drug "S" = ', round(S.std(), 5))
полученные значения средних показывают сравнительное сходство "невоздействия" на память человека препарата типа Т и плацебо S. Использование антидепрессанта типа А заметно влияет на работу памяти человека. Дисперсии величин не отличаются более чем в 2 раза. Проведем исследование
N = A.shape[0] + T.shape[0] + S.shape[0] # Общее число элементов
n = A.shape[0] # Число элементов в каждой группе (объемы групп равны)
m = 3 # число групп
# общее среднее значение
mean_global = (A.mean() + T.mean() + S.mean())/3
print('Общее среднее значение = ', mean_global)
# общая сумма квадратов
def ss(ar, mean):
return sum([(el-mean)**2 for el in ar])
SST = ss(A, mean_global) + ss(T, mean_global) + ss(S, mean_global)
print('Oбщая сумма квадратов = ', round(SST, 3))
# Общее число свободы
DF = N - 1
print('Общее число свободы = ', DF)
# Внутригрупповая сумма квадратов
SSW = ss(A, A.mean()) + ss(T, T.mean()) + ss(S, S.mean())
print('Внутригрупповая сумма квадратов = ', round(SSW, 3))
# Число степеней свободы внутригрупповая
DF_W = N - m
print('Число степеней свободы внутригрупповая', DF_W)
# Междгрупповая сумма квадратов
SSB = n*(A.mean() - mean_global)**2 + n*(T.mean() - mean_global)**2 + n*(S.mean() - mean_global)**2
print('Междгрупповая сумма квадратов = ', round(SSB, 3))
# Число степеней свободы межгрупповая
DF_B = m - 1
print('Число степеней свободы межгрупповая = ', DF_B)
Для проверки посчитаных значений можно воспользоваться известным свойством: сумма межгрупповой и внутригрупповой суммы квадратов равняется общей сумме квадратов
if (SSW + SSB - SST < 10e-5):
print("Равенство удовлетворено.")
else:
print(SSW + SSB, SST)
print('Равенство нарушено')
raise ValueError
Для проверки гипотезы можно воспользоваться F-критерием. Необходимо найти значение F критерия.
Число степеней свободы df1 = 2, df2 = 149 (inf) Распределение одностороннее, степень значимости alpha = 0.05
Для указанных параметров, F_theor = 2.9957
Использовались представленные таблицы по ссылке: http://statsoft.ru/home/textbook/default.htm
F = round((SSB/m-1) / (SSW/(N-m)), 4)
print('F-критерий = ', F, '\n\n')
F_theor = 2.9957
if F_theor > F:
print(f'{F_theor} > {F}')
print('Принимаем нулеву гипотезу о равенстве средних')
else:
print(f'{F_theor} < {F}')
print('Отклоняем нулевую гипотезу о равенстве средних')
По результатам дисперсионного анализа можно сделать следующий вывод:
Т.к дисперсионный анализ отклоняет гипотезу о равенстве средних, а в опыту принимает участие применение плацебо, то можно отверждать о наличии воздействия антидепрессантов на работу памяти. Если учитывать еще и направление воздействия, то в итоге можно сделать конкретное заключение по применению антидепрессаната типа Xanax (в прошлом, очень популярный в России).
"Антидепрессанты типа Xanax имеют влияние на работу памяти человека увеличивая продолжительность вспоминания информации любого рода" Эффект плацебо не проявляется
Проверим решение при помощи использованя все той же scipy библиотеки. Обработаем данные по алгоритму дисперсионного анализа и по непараметрическому критерию Краскела-Уоллиса.
(Правильность библиотеки не поддается сомнению, т.к ее использование можно заметить повсеместно и разрабаетывается сообществом довольно продолжитьельное время)
x, y, z = A.to_list(), S.to_list(), T.to_list()
KW = stats.kruskal(x, y, z)
ANOVA = stats.f_oneway(x, y, z)
print('По дисперсионному анализу получен следующий отчет\n', ANOVA)
print('По критерию Краскела-Уоллиса получен следующий отчет\n', KW)
В данных отчетах получены статистический значения критериев.
p-value - значение вероятности ошибки при отклонении нулевой гипотезы. Следовательно, как мы видем из отчетов, вероятности ошибится очень малы - нулевая гипотеза отклоняется. Данное решение совпадает с получеными расчитаными заключениями при анализе выше. Решение можно считать верным.